package com.hll.erp.config;

import com.hll.erp.util.PropertiesUtil;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.io.ResourceUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author cVzhanshi
 * @create 2021-06-19 13:27
 */
@Configuration
public class ShiroConfig {
  @Autowired PropertiesUtil propertiesUtil;

  /** 生命周期，之前不是static，后面发现无法导入propertiesUtil 注解支持 */
  @Bean
  public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }

  @Bean
  public ShiroFilterFactoryBean getShiroFilterFactoryBean(
      @Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
    ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
    bean.setSecurityManager(defaultWebSecurityManager);
    Map<String, String> filterMap = new LinkedHashMap<>();
    bean.setFilterChainDefinitionMap(filterMap);
    bean.setLoginUrl("/user/login");
    return bean;
  }

  @Bean
  public DefaultWebSecurityManager securityManager(
      @Qualifier("userRealm") UserRealm userRealm,
      @Qualifier("ehCacheManager") EhCacheManager cache) {
    DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
    manager.setRealm(userRealm);
    manager.setCacheManager(cache);
    return manager;
  }

  @Bean
  public EhCacheManager ehCacheManager() {
    EhCacheManager ehCacheManager = new EhCacheManager();
    InputStream is = null;
    try {
      is = ResourceUtils.getInputStreamForPath("classpath:ehcache/ehcache-shiro.xml");
    } catch (IOException e) {
      e.printStackTrace();
    }
    net.sf.ehcache.CacheManager cacheManager = new net.sf.ehcache.CacheManager(is);
    ehCacheManager.setCacheManager(cacheManager);
    return ehCacheManager;
  }

  @Bean
  public UserRealm userRealm(
      @Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher hashedCredentialsMatcher) {
    UserRealm userRealm = new UserRealm();
    userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
    return userRealm;
  }

  /** 添加cache */
  @Bean
  public EhCacheManager getCache() {
    return new EhCacheManager();
  }

  /** 加密 */
  @Bean
  public HashedCredentialsMatcher hashedCredentialsMatcher() {
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    hashedCredentialsMatcher.setHashAlgorithmName(propertiesUtil.getAlgorithm());
    hashedCredentialsMatcher.setHashIterations(propertiesUtil.getHashIteration());
    return hashedCredentialsMatcher;
  }

  /** 添加注解支持 */
  @Bean
  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator =
        new DefaultAdvisorAutoProxyCreator();
    defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
    return defaultAdvisorAutoProxyCreator;
  }

  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
      SecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
    advisor.setSecurityManager(securityManager);
    return advisor;
  }

  // 配置sessionDAO
  @Bean(name = "sessionDAO")
  public MemorySessionDAO getMemorySessionDAO() {
    MemorySessionDAO sessionDAO = new MemorySessionDAO();
    return sessionDAO;
  }

  // 配置shiro session 的一个管理器
  @Bean(name = "sessionManager")
  public DefaultWebSessionManager getDefaultWebSessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
    sessionManager.setGlobalSessionTimeout(60 * 60 * 1000);
    sessionManager.setSessionDAO(getMemorySessionDAO());
    return sessionManager;
  }
}
